209. 长度最小的子数组

209. 长度最小的子数组

题目链接
代码随想录

分析

注意,我们只需要分析长度最小子数组的长度,只需要返回这个长度数字即可:用一个数字来表示最小长度,然后有更小的就更新它,最后返回这个数字即可。

其实代码随想录里的题解说这是滑动窗口的方法,其实我觉得本质上还是双指针法,而且代码随想录里的写法太复杂了,不利于记忆,所以这里就采用我自己的写法。

如何找到符合要求的子数组呢?
从慢指针到快指针的子数组 [slow,fast] 为当前子数组

解题

public int minSubArrayLen(int target, int[] nums) {
	// 默认给一个值,第一次更新的时候,只要实际值小于这个值就行,可以用 Integer.MAX_VALUE ,不过用 nums.length+1 就够了
    int maxLength = nums.length+1;
    int subLength = maxLength;
	// 因为快慢指针都从0开始,此时相当于以及指定了一个子数组,因此此时子数组的元素和就是nums[0]
    int subSum = nums[0];
	// 快慢指针都从0开始
    int slow =0,fast =0;
    for(;;){
        if(subSum<target){
            // 元素和小于指定值,移动快指针
            fast++;
			// 跳出循环的条件就是快指针到 nums.length
            if(fast>nums.length-1){
                break;
            }
            // 移动快指针之后,子数组元素和也要更新
            subSum+=nums[fast];
        }else{
            // 元素和大于等于指定值,开始计算子数组长度
            int nowLength = fast-slow+1;
            if(nowLength<subLength){
	            // 比上一次计算的值小,才更新
				subLength = nowLength;
            }
            // 移动慢指针
            slow++;
            // 移动慢指针之后,子数组元素和也要更新
            subSum-=nums[slow];
            
        }
    }
    // 没有找到满足要求的子数组,返回0
    if(subLength==maxLength){
        return 0;
    }
    // 返回 subLength
    return subLength;
}

相关题

26. 删除有序数组中的重复项
27. 移除元素
283. 移动零
844. 比较含退格的字符串
977. 有序数组的平方
移动窗口
904. 水果成篮
76. 最小覆盖子串